home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / unix / volume5 / untic < prev    next >
Encoding:
Text File  |  1986-11-30  |  13.5 KB  |  532 lines

  1. Newsgroups: mod.sources
  2. Subject: untic - decompile terminfo description file.
  3. Approved: jpn@panda.UUCP
  4.  
  5. Mod.sources:  Volume 5, Issue 15
  6. Submitted by: Dave Regan <talcott!cmcl2!hp-pcd!orstcs!regan>
  7.  
  8. #! /bin/sh
  9. # This is a shell archive, meaning:
  10. # 1. Remove everything above the #! /bin/sh line.
  11. # 2. Save the resulting text in a file.
  12. # 3. Execute the file with /bin/sh (not csh) to create the files:
  13. #    README
  14. #    untic.1
  15. #    Makefile
  16. #    untic.c
  17. # This archive created: Wed May 21 23:00:29 1986
  18. export PATH; PATH=/bin:$PATH
  19. if test -f 'README'
  20. then
  21.     echo shar: will not over-write existing file "'README'"
  22. else
  23. cat << \SHAR_EOF > 'README'
  24. untic -- Decompile a "terminfo" terminal description file for System V.
  25.  
  26. I wrote the following program, "untic", because I needed to make a terminal
  27. description file which was just slightly different from one of the existing
  28. terminal descriptions.
  29.  
  30. This program looks up the description directly from the compiled description
  31. file.  Thus it produces a file, which when compiled, generated exactly the
  32. same information as was in the original file.
  33.  
  34. This "shar" file contains the following files:
  35.     README        This file
  36.     untic.1        A (very simple) manual page
  37.     Makefile    A (very simple) make file
  38.     untic.c        The program
  39.  
  40. I hope this program is of some use to people.
  41.  
  42.             Dave Regan
  43.             21 May 1986
  44.             PO Box 601
  45.             Corvallis OR 97339
  46.             hplabs!hp-pcd!orstcs!regan    (I think)
  47. SHAR_EOF
  48. fi # end of overwriting check
  49. if test -f 'untic.1'
  50. then
  51.     echo shar: will not over-write existing file "'untic.1'"
  52. else
  53. cat << \SHAR_EOF > 'untic.1'
  54. .TH UNTIC 1 Public Domain
  55. .SH NAME
  56. untic \- Uncompile terminfo terminal description files
  57. .SH SYNOPSIS
  58. .B untic
  59. .B terminal_name
  60. [
  61. .B . . .
  62. ]
  63. .SH DESCRIPTION
  64. .B untic
  65. convert the terminfo file which corresponds to the specified terminal name
  66. into a file that can be processed by
  67. .B tic.
  68. .PP
  69. If multiple terminal names are given, a terminal description is generated
  70. for each of the named terminals.
  71. The output is written on standard output.
  72. .PP
  73. It is wise to backup the original terminal description
  74. (from /usr/lib/terminfo)
  75. before compiling the generated file.
  76. .SH EXAMPLES
  77. To uncompile the terminal description for a "vt100", type:
  78. .RS
  79. untic vt100 >vt100
  80. .RE
  81. To compile this generated file, you probably need root permissions and type:
  82. .RS
  83. tic vt100
  84. .RE
  85. .SH NOTES
  86. If new capabilities are added to the terminfo database,
  87. the
  88. .B untic
  89. program will need to be modified.
  90. With luck, the new entries will go at the end of the appropriate tables.
  91. .PP
  92. Most of the capabilities are in the tables in the order that the capabilites
  93. are documented.
  94. There are a few exceptions in the string variables.
  95. .PP
  96. This program is placed into the public domain.
  97. That means that you can do anything you want to with it.
  98. .SH BUGS
  99. None known, but . . .
  100. .SH FILES
  101. The terminal descriptions are stored in
  102. .B /usr/lib/terminfo/?/*
  103. SHAR_EOF
  104. fi # end of overwriting check
  105. if test -f 'Makefile'
  106. then
  107.     echo shar: will not over-write existing file "'Makefile'"
  108. else
  109. cat << \SHAR_EOF > 'Makefile'
  110. CFLAGS = -O
  111. DESTDIR = /usr/local/bin
  112. DOCDIR = /usr/local/man/man1
  113.  
  114. untic:    untic.c
  115.     $(CC) $(CFLAGS) untic.c -o untic
  116.  
  117. lint:
  118.     lint untic.c
  119.  
  120. install:    untic
  121.     cp untic $(DESTDIR)/untic
  122.     strip $(DESTDIR)/untic
  123. #    cp untic.1 $(DOCDIR)/untic.1
  124.  
  125. clean:
  126.     rm untic
  127. SHAR_EOF
  128. fi # end of overwriting check
  129. if test -f 'untic.c'
  130. then
  131.     echo shar: will not over-write existing file "'untic.c'"
  132. else
  133. cat << \SHAR_EOF > 'untic.c'
  134. /*
  135.  * Untic.c -- Uncompile a terminfo file
  136.  *
  137.  * Usage:
  138.  *    untic terminal_name . . .
  139.  *
  140.  * This program finds the terminal description in
  141.  *    /usr/lib/terminfo/?/terminal_name
  142.  * It then converts the information into an ASCII file suitable for
  143.  * running into "tic".  The resulting file is written to standard output.
  144.  *
  145.  * Compile by:
  146.  *    cc -O -o untic untic.c
  147.  *
  148.  * It is probably a good idea to ensure that the file produced will compile
  149.  * to the original file before trusting "untic".
  150.  *
  151.  * Structure of terminfo file:
  152.  *    short    magic number
  153.  *    short    length of terminal names + NUL
  154.  *    short    length of booleans
  155.  *    short    length of numerics
  156.  *    short    length of strings
  157.  *    short    length of string table
  158.  *    chars    NUL terminated terminal name
  159.  *    chars    boolean flags for each of the possible booleans
  160.  *    shorts    values for each of the possible numerics
  161.  *    shorts    offsets (from start of strings) for each of the
  162.  *        possible strings
  163.  *    chars    NUL terminated strings for each of the defined strings
  164.  *
  165.  * Most of the variables are in the order that the documentation lists
  166.  * them.  This is important, as the information is stored in the file
  167.  * based upon the ordinal position of the variable.  Some of the string
  168.  * variables are not in order.  Presumably, if they add more variables,
  169.  * it will be to the end of the list, and not in the middle.
  170.  *
  171.  * This has been tested on
  172.  *    Plexus P20 (M68010), System 5 Release 2 (I think)
  173.  *
  174.  * Bugs:
  175.  *    The longest string capability is limited to 4096 bytes.  If a longer
  176.  *    string is encountered, the program will do unpredicatable things.
  177.  *    (Who uses strings that long anyway?)  The longest that the terminfo
  178.  *    file can be is 4096 bytes anyway, so this isn't too big a problem.
  179.  *
  180.  * Credits:
  181.  *    Written by Dave Regan
  182.  *    orstcs!regan
  183.  *    16 May 86
  184.  *
  185.  *    I disclaim that this program does anything useful.  It might also
  186.  *    do accidental damage.  Backup your original terminfo files.
  187.  *
  188.  *    This program is public domain.  That means you can do anything
  189.  *    you want with it.
  190.  */
  191.  
  192.  
  193. #include <stdio.h>
  194. #ifdef QC
  195. #define    OPEN_MODE    "rb"    /* Mode used to open terminfo files    */
  196. #define    void    int        /* Sigh . . .                */
  197. #else        /* QC */
  198. #include <ctype.h>
  199. #define    OPEN_MODE    "r"    /* Mode used to open terminfo files    */
  200. #endif        /* QC */
  201. #ifndef TRUE
  202. #define    TRUE    1
  203. #define    FALSE    0
  204. #endif        /* TRUE */
  205.  
  206. #define    DEBUG    FALSE        /* TRUE/FALSE to enable debugging output */
  207.  
  208. #ifdef BSD
  209. #define    TERMINFO_DIR    "/usr/static/sys5r2v2/usr/lib/terminfo"
  210. #endif        /* BSD */
  211. #ifndef TERMINFO_DIR
  212. #define    TERMINFO_DIR    "/usr/lib/terminfo"
  213. #endif        /* TERMINFO_DIR */
  214.  
  215.  
  216. #define    MAGIC    0x011A        /* Terminfo magic number        */
  217. #define    MAXLINE    65        /* Longest emited line            */
  218. #define    MAX_CAP    4096        /* Longest single capability        */
  219.  
  220. extern    char *strcpy();
  221.  
  222. int    line_len;        /* Current length of line        */
  223.  
  224. main(argc, argv)
  225.   int    argc;            /* Number of paramters            */
  226.   char    *argv[];        /* The parameters themselves        */
  227.     {
  228.     char subdir[2];        /* Subdirectory name            */
  229.     FILE *file;
  230.     extern FILE *fopen();
  231.  
  232. #ifdef CPM
  233.     wildexp(&argc, &argv);
  234. #endif        /* CPM */
  235.  
  236.     /* Change directory to the working directory            */
  237.     (void)chdir(TERMINFO_DIR);
  238.  
  239.     /* Go through the arguments                        */
  240.     subdir[1] = '\0';
  241.     if (argc == 1)
  242.     convert(stdin, "stdin");
  243.     else
  244.     {
  245.     while (--argc)
  246.         {
  247.         ++argv;
  248.         subdir[0] = argv[0][0];
  249.         (void)chdir(subdir);
  250.         if ((file = fopen(*argv, OPEN_MODE)) == NULL)
  251.         {
  252.         perror(*argv);
  253.         }
  254.         else
  255.         {
  256.         convert(file, *argv);
  257.         (void)fclose(file);
  258.         }
  259.         (void)chdir("..");
  260.         }
  261.     }
  262.     }
  263.  
  264.  
  265. /*
  266.  * Addchar -- Add a character
  267.  */
  268. char *
  269. addchar(cptr, ch)
  270.   char    *cptr;
  271.   int    ch;
  272.     {
  273.     char *addstr(), *addoctal();
  274.  
  275.     if (ch == 0x1B)
  276.     return (addstr(cptr, "\\E"));
  277.     if (ch == '\n')
  278.     return (addstr(cptr, "\\n"));
  279.     if (ch == '\r')
  280.     return (addstr(cptr, "\\r"));
  281.     if (ch == '\t')
  282.     return (addstr(cptr, "\\t"));
  283.     if (ch == '\b')
  284.     return (addstr(cptr, "\\b"));
  285.     if (ch == '\f')
  286.     return (addstr(cptr, "\\f"));
  287.     if (ch == ' ')
  288.     return (addstr(cptr, "\\s"));
  289.     if (ch == '^')
  290.     return (addstr(cptr, "\\^"));
  291.     if (ch == '\\')
  292.     return (addstr(cptr, "\\\\"));
  293.     if (ch == ',')
  294.     return (addstr(cptr, "\\,"));
  295.     if (ch == ':')
  296.     return (addstr(cptr, "\\:"));
  297.     if (ch >= ('A' - '@') && ch <= ('Z' - '@'))
  298.     {
  299.     *cptr++ = '^';
  300.     *cptr++ = ch + '@';
  301.     return (cptr);
  302.     }
  303. #ifdef notdef
  304.     /*
  305.      * Did you know that \r \n \f \t are NOT control characters
  306.      * as defined by "iscntrl" under BSD 4.2?  I find that
  307.      * rather odd.
  308.      */
  309. #endif        /* notdef */
  310.     if (iscntrl(ch) || isspace(ch) || ch > 0x7F)
  311.         return (addoctal(cptr, ch));
  312.     *cptr++ = ch;
  313.     return (cptr);
  314.     }
  315.  
  316.  
  317. /*
  318.  * Addoctal -- Add an octal character
  319.  *
  320.  * Use sprintf just in case "0" through "7" are not contiguous.  Some
  321.  * machines are weird.
  322.  */
  323. char *
  324. addoctal(cptr, ch)
  325.   char    *cptr;
  326.   int    ch;
  327.     {
  328.     char *addstr();
  329.  
  330.     ch &= 0xFF;
  331.  
  332.     if (ch == 0x80)
  333.     return (addstr(cptr, "\\0"));
  334.     (void)sprintf(cptr, "\\%03o", ch);
  335.     while (*cptr != '\0')
  336.     cptr++;
  337.     return (cptr);
  338.     }
  339.  
  340.  
  341. /*
  342.  * Addstr -- Add a string to the capability
  343.  */
  344. char *
  345. addstr(cptr, str)
  346.   char    *cptr, *str;
  347.     {
  348.     while (*str)
  349.     *cptr++ = *str++;
  350.     return (cptr);
  351.     }
  352.  
  353.  
  354. /*
  355.  * Convert -- Do the actual conversion
  356.  */
  357. convert(file, name)
  358.   FILE    *file;        /* The file with the compiled information    */
  359.   char    *name;        /* Printable version of the filename        */
  360.     {
  361.     int    ch, val, i, j, fail;
  362.     int name_length, bool_length, num_length, str_length, s_length;
  363.     char capability[MAX_CAP+1], *cptr, *addchar();
  364.  
  365.     static char *booleans[] =    /* Names of boolean variables, in order    */
  366.     { "bw", "am", "xsb", "xhp", "xenl", "eo", "gn", "hc", "km",
  367.       "hs", "in", "da", "db", "mir", "msgr", "os", "eslok", "xt",
  368.       "hz", "ul", "xon" };
  369.     static char *numerics[] =    /* Names of numeric variables, in order    */
  370.     { "cols", "it", "lines", "lm", "xmc", "pb", "vt", "wsl" };
  371.     static char *strings[] =    /* Names of string variables, not in strict
  372.                    order.  Makes things a little harder    */
  373.     { "cbt", "bel", "cr", "csr", "tbc", "clear", "el", "ed", "hpa",
  374.       "cmdch", "cup", "cud1", "home", "civis", "cub1", "mrcup",
  375.       "cnorm", "cuf1", "ll", "cuu1", "cvvis", "dch1", "dl1", "dsl",
  376.       "hd", "smacs", "blink", "bold", "smcup", "smdc", "dim", "smir",
  377.       "invis", "prot", "rev", "smso", "smul", "ech", "rmacs", "sgr0", 
  378.       "rmcup", "rmdc", "rmir", "rmso", "rmul", "flash", "ff", "fsl",
  379.       "is1", "is2", "is3", "if", "ich1", "il1", "ip", "kbs", "ktbc",
  380.       "kclr", "kctab", "kdch1", "kdl1", "kcud1", "krmir", "kel", "ked",
  381.       "kf0", "kf1", "kf10", "kf2", "kf3", "kf4", "kf5", "kf6", "kf7",
  382.       "kf8", "kf9", "khome", "kich1", "kil1", "kcub1", "kll", "knp",
  383.       "kpp", "kcuf1", "kind", "kri", "khts", "kcuu1", "rmkx", "smkx", 
  384.       "lf0", "lf1", "lf10", "lf2", "lf3", "lf4", "lf5", "lf6", "lf7",
  385.       "lf8", "lf9", "rmm", "smm", "nel", "pad", "dch", "dl", "cud",
  386.       "ich", "indn", "il", "cub", "cuf", "rin", "cuu", "pfkey", "pfloc",
  387.       "pfx", "mc0", "mc4", "mc5", "rep", "rs1", "rs2", "rs3", "rf",
  388.       "rc", "vpa", "sc", "ind", "ri", "sgr", "hts", "wind", "ht", "tsl",
  389.       "uc", "hu", "iprog", "ka1", "ka3", "kb2", "kc1", "kc3", "mc5p" };
  390.     int str_cap[sizeof(strings) / sizeof(char *)];
  391.  
  392.     /* Check the magic number out                    */
  393.     if (get2(file) != MAGIC)
  394.     {
  395.     fprintf(stderr, "\"%s\" is not a terminfo file\n", name);
  396.     return;
  397.     }
  398.  
  399.     /* Get the rest of the header information                */
  400.     name_length = get2(file);    /* Get the length of the terminal names    */
  401.     bool_length = get2(file);    /* Get the length of the booleans    */
  402.     num_length = get2(file);    /* Get the length of the numerics    */
  403.     str_length = get2(file);    /* Get the length of the strings    */
  404.     s_length = get2(file);    /* Get the length of the string tables    */
  405.  
  406.     /* Check for too many data items                    */
  407.     fail = FALSE;
  408.     if (bool_length > (sizeof(booleans) / sizeof(char *)))
  409.     {
  410.     fprintf(stderr, "Boolean variables have been added to terminfo.\n");
  411.     fail = TRUE;
  412.     }
  413.     if (num_length > (sizeof(numerics) / sizeof(char *)))
  414.     {
  415.     fprintf(stderr, "Numeric variables have been added to terminfo.\n");
  416.     fail = TRUE;
  417.     }
  418.     if (str_length > (sizeof(strings) / sizeof(char *)))
  419.     {
  420.     fprintf(stderr, "String variables have been added to terminfo.\n");
  421.     fail = TRUE;
  422.     }
  423.     if (fail)
  424.     {
  425.     fprintf(stderr,
  426. "Update the \"untic\" program.  Use \"xxx\" if needed.  Good luck.\n");
  427.     return;
  428.     }
  429.  
  430.     /* Time to get real information                    */
  431.     while ((ch = getc(file)) != '\0' && ch != EOF)
  432.     putchar(ch);
  433.     printf(",\n\t");
  434.  
  435.     /* Send out the non-null boolean variables                */
  436.     line_len = 0;
  437.     for (i = 0; i < bool_length; i++)
  438.     {
  439.     if ((ch = getc(file)) != 0)
  440.         emit(booleans[i]);
  441.     }
  442.  
  443.     /* The rest of the file is on a 16 bit boundary, so adjust the file    */
  444.     if ((name_length + bool_length) & 0x01)
  445.     (void)getc(file);
  446.  
  447.     /* Get the numeric variables                    */
  448.     for (i = 0; i < num_length; i++)
  449.     {
  450.     if ((val = get2(file)) != 0xFFFF)
  451.         {
  452.         (void)sprintf(capability, "%s#%d", numerics[i], val);
  453.         emit(capability);
  454.         }
  455.     }
  456.  
  457.     /* Get the string variables offsets                    */
  458.     for (i = 0; i < str_length; i++)
  459.     str_cap[i] = get2(file);
  460.  
  461.     /* Get the string variables themselves                */
  462.     for (i = 0; i < s_length; i++)
  463.     {
  464.     for (j = 0; j < str_length; j++)    /* Find the name    */
  465.         if (str_cap[j] == i)
  466.         break;
  467. #if DEBUG
  468.     if (j >= str_length)
  469.         fprintf(stderr, "Cannot find address %d\n", i);
  470. #endif        /* DEBUG */
  471.     (void)strcpy(capability, strings[j]);
  472.     cptr = &capability[strlen(capability)];
  473.     *cptr++ = '=';
  474.     for (; (ch = getc(file)) != '\0' && ch != EOF; i++)
  475.         cptr = addchar(cptr, ch);
  476.     *cptr = '\0';
  477.     emit(capability);
  478.     }
  479.  
  480.     printf("\n\n");
  481.     }
  482.  
  483.  
  484. /*
  485.  * Emit -- Emit the string
  486.  *
  487.  * Emit the given string, and append a comma.  If the line gets too long,
  488.  * send out a newline and a tab.
  489.  */
  490. emit(str)
  491.   char    *str;        /* String to emit                */
  492.     {
  493.     if ((line_len += strlen(str) + 2) > MAXLINE)
  494.     {
  495.     line_len = strlen(str) + 2;
  496.     printf("\n\t");
  497.     }
  498.     printf("%s, ", str);
  499.     }
  500.  
  501.  
  502. /*
  503.  * Get2 -- Get a two byte number
  504.  */
  505. get2(file)
  506.   FILE *file;        /* The file with the compiled information    */
  507.     {
  508.     short temp;
  509.  
  510.     temp = getc(file) & 0xFF;
  511.     return (temp + (getc(file) << 8));
  512.     }
  513.  
  514.  
  515. #ifdef CPM
  516. chdir(str)
  517.   char    *str;
  518.     {
  519.     }
  520.  
  521. perror(str)
  522.   char    *str;
  523.     {
  524.     fprintf(stderr, "Cannot open \"%s\"\n", str);
  525.     }
  526. #endif        /* CPM */
  527. SHAR_EOF
  528. fi # end of overwriting check
  529. #    End of shell archive
  530. exit 0
  531.  
  532.